<?php

namespace app\web\service;

use app\common\logic\BusesLogic;
use app\common\model\commonModel;
use app\common\model\trBusesLine;
use app\common\model\trCache;
use app\common\model\trCar;
use app\common\model\trCarList;
use app\common\model\trCarType;
use app\common\model\trDriver;
use app\common\model\trOrder;
use app\common\model\trOrderOutletsDetail;
use app\common\model\trOutletsCar;
use app\common\model\trUser;
use app\common\util\ErrorCode;
use app\common\util\Tools;

/**
 * Class Auth
 * @package app\admin\service
 * 核销员服务类
 */
class VerifierService
{
    private $returnData;
    private $params;

    public function __construct($data, $params)
    {
        $this->returnData = $data;
        $this->params = $params;
    }

    // 首页数据
    public function verifierIndex(){
        $data = commonModel::getFields(verifierTable, "nickname,prefix,mobile,status", ["openid" => request()->userLoginData["openid"]]);
        if(empty($data["mobile"])){
            $this->returnData = ErrorCode::code("fail");
            $this->returnData["msg"] = "核销员不存在";
            return $this->returnData;
        }
        $this->returnData["data"] = $data;
        return $this->returnData;
    }

    // 核销员基本信息
    public function verifierInfo(){
        $data = commonModel::getFields(verifierTable, "nickname,prefix,mobile,id_card,gender", ["openid" => request()->userLoginData["openid"]]);
        if(empty($data["mobile"])){
            return ErrorCode::code("customized", "该用户不是核销员");
        }
        $data["genderText"] = $data["gender"] == '1' ? "男" : "女";
        $this->returnData["data"] = $data;
        return $this->returnData;
    }

    // 核销员基本信息
    public function updateVerifierInfo(){
        $field = ["nickname" => "require", "prefix" => "require", "mobile" => "require", "id_card" => "require", "gender" => "require"];
        $data = [];
        foreach ($field as $k => $v) {
            $ks = parse_name($k); //转换字段，变驼峰
            if(!isset($this->params[$ks])){
                return ErrorCode::code('params_not_exist', $ks);
            }
            $data[$k] = $this->params[$ks];
        }
        $res = commonModel::toUpdate(verifierTable, $data, ["openid" => request()->userLoginData["openid"]]);
        if(isset($res["code"])) {
            return $res;
        }
        if(!$res){
            $this->returnData = ErrorCode::code("fail");
            $this->returnData["msg"] = "更新失败";
        }
        return $this->returnData;
    }

    // 更新核销员状态
    public function updateVerifierStatus(){ // status  状态：1正常；2休息；3注销
        if(empty($this->params['status'])){
            return ErrorCode::code("params_not_exist", "status");
        }
        if(!in_array($this->params["status"], [1,2])){
            return ErrorCode::code("params_error", "status（1正常；2休息）");
        }
        $res = commonModel::toUpdate(verifierTable, ["status" => $this->params["status"]], ["openid" => request()->userLoginData["openid"]]);
        if(!$res){
            $this->returnData = ErrorCode::code("fail");
            $this->returnData["msg"] = "更新失败";
        }
        return $this->returnData;
    }

    // 今天的所有班次列表
    public function verifierClassesList(){
        $driverModel = new trDriver();
        $driverId = $driverModel->getValue("id", ["openid" => request()->userLoginData["openid"]]);
        if(!$driverId){
            if(empty(commonModel::getCount(verifierTable, ["openid" => request()->userLoginData["openid"]]))){
                return ErrorCode::code("customized", "该用户不是核销员也不是司机");
            }else{
                $filter = [["status", "=",  1]];
            }
        }else{
            $filter = [["status", "=",  1], ["driver", "REGEXP", "^{$driverId},|{$driverId},|{$driverId}$"]]; //正则匹配司机ID
        }
        $filter[] = ["mall_id", "=", request()->mallData["id"]];
        $page = isset($this->params['page']) ? intval($this->params['page']) : 1;
        $pageSize = isset($this->params['pageSize']) ? intval($this->params['pageSize']) : 10;
        $queryTime = isset($this->params['time']) ? (is_numeric($this->params['time']) ? date("Y-m-d", $this->params['time']) : date("Y-m-d", strtotime($this->params['time']))) : date("Y-m-d");
        $model = new trBusesLine();
        if(($redisObject = redis_object()) !== false) {// 是redis缓存
            $data = $model->getFields(
                "id,address_from,address_to,open_default,open_weekend,open_date,date_between,default_adult_price,weekend_adult_price,date_adult_price,car_type",
                $filter, false, false
            );
        }else{
            $field = "id,province_code_from,city_code_from,area_code_from,address_from,province_code_to,city_code_to,area_code_to,address_to,
                    open_default,open_weekend,open_date,default_adult_price,weekend_adult_price,date_adult_price,car_type";
            $data = $model->getFields($field, $filter, false, false);
        }
        if(!$data){
            $this->returnData['data'] = [];
        }else {
            $returnData = [];
            $totalCount = $currentCount = 0; // $totalCount到本页总共拿到班次的总数量，$currentCount到当页获取到的总数量
            if($page == "1"){ // 用户从第一页开始，就记录他的开始时间，后面就用这个开始时间做校验
                $startTime = time();
                // 放缓存表，过今天24点就过期，会删除
                trCache::saveCache(["key" => "userVerifierTime_".request()->userLoginData["openid"], "value" => $startTime, "time" => mktime(23, 59, 59) - time()]);
                $currentCount = 0;
            }else{
                $startTime = trCache::getValue("value", ["key" => "userVerifierTime_" . request()->userLoginData["openid"]]);
                $currentCount = ($page-1) * $pageSize;
            }
            $carTypeModel = new trCarType();
            $k = 0; // key 计量开始
            foreach ($data as $item) {
                $classesData = $model->getClassesCache($item["id"], $queryTime); // 获取今天线路的所有班次数据
                if(empty($classesData)){
                    continue;
                }
                if(date("Y-m-d", $startTime) == $queryTime) { // 今天的要过滤已经过期的班次数据
                    foreach ($classesData as $tempK => $tempClasses) {
                        if ($tempClasses["shift"] < date("H:i", $startTime)) {
                            unset($classesData[$tempK]); // 过滤已经过期的班次数据
                        }
                    }
                    $classesData = array_values($classesData);
                }
                $totalCount += count($classesData);
                if($page != "1"){ // 从第二页开始判断
                    if($currentCount > $totalCount){
                        continue;
                    }elseif(count($returnData) == "0"){
                        $k = $currentCount + count($classesData)-$totalCount;
                    }
                }
                $classesInfo = $model->getClassesInfoCache($item["id"]);
                if($classesInfo["startTime"] <= $queryTime && $classesInfo["lastTime"] >= $queryTime){ // 当前日期在班次允许内
                    for(;$k<count($classesData);){
                        if(count($returnData) >= $pageSize){
                            break;
                        }
                        $returnData[] = $classesData[$k];
                        $k++;
                    }
                    if(!empty($returnData)){
                        $item = Tools::transferFields($item->getData()); // 转为驼峰
                        if ($redisObject !== false) {// 是redis缓存
                            $item["showPrice"] = BusesLogic::getShowPrice($item, BusesLogic::getJudgeOpenType($item, date("Y-m-d")));
                            $tempData = $model->getPCACacheData($item["id"]);
                            $tempData["addressFrom"] = $item["addressFrom"];
                            $tempData["addressTo"] = $item["addressTo"];
                            list($item["addressFrom"], $item["addressTo"]) = BusesLogic::getShowAddress($tempData);
                            unset($tempData);
                        } else {
                            $item["showPrice"] = BusesLogic::getShowPrice($item, BusesLogic::getJudgeOpenType($item, date("Y-m-d")));
                            list($item["addressFrom"], $item["addressTo"]) = BusesLogic::getShowAddress($item);
                        }
                        foreach ($returnData as $tk => $tmp){
                            if(empty($tmp["id"])) {
                                if(!isset($tmp["deferTicket"])){ // 延期余票（等待付款或者退款）
                                    $tmp["deferTicket"] = 0;
                                }
                                if(empty($verifierTmp["{$item["id"]}_{$tmp["shift"]}"])){ // 已核销人数
                                    $verifierTmp["{$item["id"]}_{$tmp["shift"]}"] = intval(trCache::getValue("value",["key" => "busesLineVerifier_{$item["id"]}_{$tmp["shift"]}"]));
                                }
                                // $verifierNum 待核销人数  ticketNumber 总票数  standbyTicket 可售票数
                                $verifierNum = $tmp["ticketNumber"] - $tmp["standbyTicket"] - $tmp["deferTicket"] - $verifierTmp["{$item["id"]}_{$tmp["shift"]}"];
                                if(!$verifierNum){ // 没有核销人数的班次不显示了
                                    unset($returnData[$tk]);
                                    continue;
                                }
                                if(empty($carData[$item["carType"]])){
                                    $carData[$item["carType"]] = $carTypeModel->getValue("name", ["id" => $item["carType"]]);
                                }
                                $returnData[$tk] = array_merge($tmp, [
                                    "id" => $item["id"], "showPrice" => $item["showPrice"], "addressFrom" => $item["addressFrom"], "addressTo" => $item["addressTo"],
                                    "plateNumber" => $carData[$item["carType"]], "verifierNum" => $verifierNum
                                ]);
                                $returnData[$tk]["shift"] = date("H:i", strtotime("$queryTime {$tmp["shift"]}")); // 去掉秒
                            }
                        }
                        if(count($returnData) >= $pageSize){
                            break;
                        }
                        if((count($returnData)-$currentCount)> 0 && (count($returnData)-$currentCount) < count($classesData)){
                            $k = count($returnData);
                        }else {
                            $k = 0;
                        }
                    }
                }
            }
            $this->returnData["data"] = array_values($returnData);
        }
        return $this->returnData;
    }

    public function getClassesInfo(){
        $driverModel = new trDriver();
        if(!$driverModel->getCount(["openid" => request()->userLoginData["openid"]])){
            if(empty(commonModel::getCount(verifierTable, ["openid" => request()->userLoginData["openid"]]))){
                return ErrorCode::code("customized", "该用户不是核销员也不是司机");
            }
        }
        if(empty($this->params['lineId'])){
            return ErrorCode::code("params_not_exist", "线路ID");
        }
        if (empty($this->params['chooseTime'])) {
            return ErrorCode::code("params_not_exist", "出发时间");
        }
        $model = new trBusesLine();
        if(($redisObject = redis_object()) !== false) {// 是redis缓存
            $data = $model->getFields(
                "id,address_from,address_to,open_default,open_weekend,open_date,date_between,default_adult_price,weekend_adult_price,date_adult_price,car_type",
                ["id" => $this->params["lineId"]], true, false);
        }else{
            $field = "id,province_code_from,city_code_from,area_code_from,address_from,province_code_to,city_code_to,area_code_to,address_to,
                    open_default,open_weekend,open_date,date_between,default_adult_price,weekend_adult_price,date_adult_price,car_type";
            $data = $model->getFields($field, ["id" => $this->params["lineId"]], true, false);
        }
        if(!$data){
            $this->returnData['data'] = [];
        }else {
            $currentTime = date("Y-m-d", strtotime($this->params['chooseTime']));
            $classesData = $model->getClassesCache($data["id"], $currentTime); // 班次数据
            if(!empty($classesData)){ // 没有班次数据，就忽略
                $classesData = Tools::array_replace($classesData, "shift");
                $rule = BusesLogic::getTimeRule(date("Y-m-d") . key($classesData));
                if(isset($classesData[date("$rule", strtotime($this->params['chooseTime']))])) {
                    $currentClasses = $classesData[date("$rule", strtotime($this->params['chooseTime']))];
                    if ($redisObject !== false) {// 是redis缓存
                        $data["showPrice"] = BusesLogic::getShowPrice($data, BusesLogic::getJudgeOpenType($data, $currentTime));
                        $tempData = $model->getPCACacheData($data["id"]);
                        $tempData["addressFrom"] = $data["addressFrom"];
                        $tempData["addressTo"] = $data["addressTo"];
                        list($data["addressFrom"], $data["addressTo"]) = BusesLogic::getShowAddress($tempData);
                    } else {
                        $data["showPrice"] = BusesLogic::getShowPrice($data, BusesLogic::getJudgeOpenType($data, $currentTime));
                        list($data["addressFrom"], $data["addressTo"]) = BusesLogic::getShowAddress($data);
                    }
                    if(!isset($currentClasses["deferTicket"])){ // 延期余票（等待付款或者退款）
                        $currentClasses["deferTicket"] = 0;
                    }
                    $verifierNum = intval(trCache::getValue("value", ["key" => "busesLineVerifier_{$data["id"]}_{$currentClasses["shift"]}"])); // $verifierNum 已核销人数
                    $currentClasses["shift"] = $currentTime . " {$currentClasses["shift"]}"; // 出发时间
                    $currentClasses["verifierNum"] = $verifierNum; // 已核销人数
                    // ticketNumber 总票数  standbyTicket 可售票数  deferTicket 延期余票
                    $currentClasses["saleTicket"] = $currentClasses["ticketNumber"] - $currentClasses["standbyTicket"] - $currentClasses["deferTicket"];
                    $carModel = new trCar();
                    $carTypeModel = new trCarType();
                    $carData = $carModel->getFields("plate_number", ["car_type" => $data["carType"]], true, false);
                    $carData["plateNumber"] = isset($carData["plateNumber"]) ? $carData["plateNumber"] : "";
                    $this->returnData['data'] = array_merge($currentClasses, [
                        "id" => $data["id"], "showPrice" => $data["showPrice"], "addressFrom" => $data["addressFrom"], "addressTo" => $data["addressTo"],
                        "plateNumber" => $carData["plateNumber"], "carName" => $carTypeModel->getValue("name", ["id" => $data["carType"]]), "typeName" => "巴士路线",
                        "checkTicket" => 0
                    ]);
                    // 只有今天的日期才能开始验票
                    if(date("Y-m-d") == $currentTime &&
                        $currentClasses["ticketNumber"] - $currentClasses["standbyTicket"] - $currentClasses["deferTicket"] - $verifierNum > 0){
                        $this->returnData['data']["checkTicket"] = 1;
                    }
                }else{
                    $this->returnData['data'] = [];
                }
            }else{
                $this->returnData['data'] = [];
            }
        }
        return $this->returnData;
    }

    // 核销订单是否正常 - 巴士线路 ，没有分配说法
    public function getWriteOff(){
        $driverModel = new trDriver();
        if(!$driverModel->getCount(["openid" => request()->userLoginData["openid"], "status" => 1])){
            if(empty(commonModel::getCount(verifierTable, ["openid" => request()->userLoginData["openid"], "status" => 1]))){
                return ErrorCode::code("customized", "核销功能暂时不能使用");
            }
        }
        if(empty($this->params["orderSn"])){
            return ErrorCode::code("params_not_exist", "订单编号");
        }
        if(empty($this->params["time"])){
            return ErrorCode::code("params_not_exist", "班次时间");
        }
        if(empty($this->params["lineId"])){
            return ErrorCode::code("params_not_exist", "线路ID");
        }
        $this->returnData["data"] = ["checkTicket" => 0];
        $orderModel = new trOrder();
        $orderData = $orderModel->getFields("line_id,ride_number,status,reserve_time", ["order_sn" => $this->params["orderSn"], "type" => 2], true, false);
        if(empty($orderData)){
            $this->returnData["msg"] = "订单不存在";
            return $this->returnData;
        }
        if($orderData["status"] == "1"){
            $this->returnData["msg"] = "订单未付款";
            return $this->returnData;
        }
        if($orderData["reserveTime"] != $this->params["time"] || $this->params["lineId"] != $orderData["lineId"]){
            $this->returnData["msg"] = "订单的班次和线路不一致";
            return $this->returnData;
        }
        $cacheNum = intval(trCache::getValue("value", ["key" => "orderVerifier_{$this->params["orderSn"]}"])); // 订单已核销数
        if($cacheNum >= $orderData["rideNumber"]){
            $this->returnData["msg"] = "订单已经核销了";
            return $this->returnData;
        }
        $model = new trBusesLine();
        $reserveTime = explode(" ", $orderData["reserveTime"]);
        $classesData = $model->getClassesCache($orderData["lineId"], $reserveTime[0]); // 班次数据
        if(!empty($classesData)) { // 没有班次数据，就忽略
            $classesData = Tools::array_replace($classesData, "shift");
            if (isset($classesData[$reserveTime[1]])) {
                $verifierNum = intval(trCache::getValue("value", ["key" => "busesLineVerifier_{$orderData["lineId"]}_{$reserveTime[1]}"])); // 已核销人数
                $num = $classesData[$reserveTime[1]]["ticketNumber"] - $classesData[$reserveTime[1]]["standbyTicket"] - $classesData[$reserveTime[1]]["deferTicket"]; // 一共要核销的数
                if($num >= $verifierNum) { // 检查已核销票数是否小于总核销票数
                    trCache::saveCache([
                        "key" => "busesLineVerifier_{$orderData["lineId"]}_{$reserveTime[1]}",
                        "value" => $verifierNum + 1,
                        "time" => mktime(23, 59, 59) - time() // 有效期到今天24点
                    ]); // 保存已核销人数
                    // 记录改订单已经核销了，有效期到今天24点，订单有多少个人，就可以核销几次
                    trCache::saveCache(["key" => "orderVerifier_{$this->params["orderSn"]}", "value" => $cacheNum + 1, "time" => mktime(23, 59, 59) - time()]);
                    $orderModel->doUpdate(["status" => 8], ["order_sn" => $this->params["orderSn"]]); // 核销成功订单变成完成状态
                }
            }else{
                $this->returnData["msg"] = "订单的班次不存在";
                return $this->returnData;
            }
        }
        $this->returnData["data"] = ["checkTicket" => 1];
        return $this->returnData;
    }

    // 核销租车
    public function handleOutlets(){
        if(empty($this->params["orderSn"])){
            return ErrorCode::code("params_not_exist", "订单编号");
        }
        $userData = trUser::where("id", request()->userLoginData["id"])->field("user_type")->find();
        if($userData->user_type != "2"){
            return ErrorCode::code("customized", "无权限，用户不是核销员");
        }
        $data = trOrder::alias("o")->leftJoin(trOrderOutletsDetail::getTable()." od", "o.id=od.order_id")
            ->leftJoin(trOutletsCar::getTable()." oc", "oc.id=od.oc_id")
            ->field("o.id,o.status,od.oc_id,od.plate_number,oc.over_stock,oc.id as outletsCarId")
            ->where(["o.order_sn" => $this->params["orderSn"]])
            ->find();
        if(empty($data)){
            return ErrorCode::code("customized", "订单不存在");
        }
        if($data->status == '8'){
            return ErrorCode::code("customized", "订单已核销");
        }
        trOutletsCar::where("id", $data->oc_id)->update(["over_stock" => $data->over_stock + 1]);
        trCarList::where(["type" => 5, "attr_id" => $data->outletsCarId, "plate_number" => $data->plate_number])->update(["use" => 0]);
        trOrder::where("id", $data->id)->update(["status" => 8]);
        return $this->returnData;
    }
}